floating_point.hpp
namespace type_safe
{
template <typename FloatT>
class floating_point;
template <typename A, typename B>
constexpr bool operator<(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr bool operator<(const A& a, const floating_point<B>& b);
template <typename A, typename B>
constexpr bool operator<(const floating_point<A>& a, const B& b);
template <typename A, typename B>
constexpr bool operator<=(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr bool operator<=(const A& a, const floating_point<B>& b);
template <typename A, typename B>
constexpr bool operator<=(const floating_point<A>& a, const B& b);
template <typename A, typename B>
constexpr bool operator>(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr bool operator>(const A& a, const floating_point<B>& b);
template <typename A, typename B>
constexpr bool operator>(const floating_point<A>& a, const B& b);
template <typename A, typename B>
constexpr bool operator>=(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr bool operator>=(const A& a, const floating_point<B>& b);
template <typename A, typename B>
constexpr bool operator>=(const floating_point<A>& a, const B& b);
//=== Binary operations ===//
template <typename A, typename B>
constexpr 'hidden' operator+(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator+(const A& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator+(const floating_point<A>& a, const B& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator-(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator-(const A& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator-(const floating_point<A>& a, const B& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator*(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator*(const A& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator*(const floating_point<A>& a, const B& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator/(const floating_point<A>& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator/(const A& a, const floating_point<B>& b) noexcept;
template <typename A, typename B>
constexpr 'hidden' operator/(const floating_point<A>& a, const B& b) noexcept;
template <typename Char, class CharTraits, typename FloatT>
std::basic_istream<Char, CharTraits>& operator>>(std::basic_istream<Char, CharTraits>& in, floating_point<FloatT>& f);
template <typename Char, class CharTraits, typename FloatT>
std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& out, const floating_point<FloatT>& f);
}
namespace std
{
}
type_safe::floating_point
[types]template <typename FloatT>
class floating_point
{
public:
using floating_point_type = FloatT;
template <typename T>
constexpr floating_point(const T& val) noexcept;
template <typename T>
constexpr floating_point(const floating_point<T>& val) noexcept;
template <typename T>
floating_point& operator=(const T& val) noexcept;
template <typename T>
floating_point& operator=(const floating_point<T>& val) noexcept;
constexpr operator floating_point_type() const noexcept;
constexpr floating_point_type get() const noexcept;
constexpr floating_point operator+() const noexcept;
constexpr floating_point operator-() const noexcept;
//=== Compound assignment ===//
template <typename T>
floating_point& operator+=(const floating_point<T>& other) noexcept;
template <typename T>
floating_point& operator+=(const T& other) noexcept;
template <typename T>
floating_point& operator-=(const floating_point<T>& other) noexcept;
template <typename T>
floating_point& operator-=(const T& other) noexcept;
template <typename T>
floating_point& operator*=(const floating_point<T>& other) noexcept;
template <typename T>
floating_point& operator*=(const T& other) noexcept;
template <typename T>
floating_point& operator/=(const floating_point<T>& other) noexcept;
template <typename T>
floating_point& operator/=(const T& other) noexcept;
};
A type safe floating point class.
It is a tiny, no overhead wrapper over a standard floating point type. It behaves exactly like the built-in types except it does not allow narrowing conversions.
Requires: FloatT
must be a floating point type.
Notes: It intentionally does not provide equality or increment/decrement operators.
type_safe::floating_point::floating_point
(1) template <typename T>
constexpr floating_point(const T& val) noexcept;
(2) template <typename T>
constexpr floating_point(const floating_point<T>& val) noexcept;
Effects: Initializes the floating point with the given value.
Notes: These functions do not participate in overload resolution, if T
is not a floating point type safely convertible to this type.
type_safe::floating_point::operator=
(1) template <typename T>
floating_point& operator=(const T& val) noexcept;
(2) template <typename T>
floating_point& operator=(const floating_point<T>& val) noexcept;
Effects: Assigns the floating point the given value.
Notes: These functions do not participate in overload resolution, if T
is not a floating point type safely convertible to this type.
type_safe::floating_point::operator floating_point_type
(1) constexpr operator floating_point_type() const noexcept;
(2) constexpr floating_point_type get() const noexcept;
Returns: The stored value as the native floating point type.
type_safe::floating_point::operator+
constexpr floating_point operator+() const noexcept;
Returns: The value unchanged.
type_safe::floating_point::operator-
constexpr floating_point operator-() const noexcept;
Returns: The negative value.
(1) template <typename T>
floating_point& operator+=(const floating_point<T>& other) noexcept;
(2) template <typename T>
floating_point& operator+=(const T& other) noexcept;
(3) template <typename T>
floating_point& operator-=(const floating_point<T>& other) noexcept;
(4) template <typename T>
floating_point& operator-=(const T& other) noexcept;
(5) template <typename T>
floating_point& operator*=(const floating_point<T>& other) noexcept;
(6) template <typename T>
floating_point& operator*=(const T& other) noexcept;
(7) template <typename T>
floating_point& operator/=(const floating_point<T>& other) noexcept;
(8) template <typename T>
floating_point& operator/=(const T& other) noexcept;
Effects: Same as the operation on the floating point type.
Notes: These functions do not participate in overload resolution, if T
is not a floating point type safely convertible to this type.
type_safe::operator<
template <typename A, typename B>
constexpr bool operator<(const floating_point<A>& a, const floating_point<B>& b) noexcept;
Returns: The result of the comparison of the stored floating point value in the ts::floating_point. \notes These functions do not participate in overload resolution unless A
and B
are both floating point types. \group float_comp Comparison operators \module types
type_safe::operator<
(1) template <typename A, typename B>
constexpr bool operator<(const A& a, const floating_point<B>& b);
(2) template <typename A, typename B>
constexpr bool operator<(const floating_point<A>& a, const B& b);
(3) template <typename A, typename B>
constexpr bool operator<=(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(4) template <typename A, typename B>
constexpr bool operator<=(const A& a, const floating_point<B>& b);
(5) template <typename A, typename B>
constexpr bool operator<=(const floating_point<A>& a, const B& b);
(6) template <typename A, typename B>
constexpr bool operator>(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(7) template <typename A, typename B>
constexpr bool operator>(const A& a, const floating_point<B>& b);
(8) template <typename A, typename B>
constexpr bool operator>(const floating_point<A>& a, const B& b);
(9) template <typename A, typename B>
constexpr bool operator>=(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(10) template <typename A, typename B>
constexpr bool operator>=(const A& a, const floating_point<B>& b);
(11) template <typename A, typename B>
constexpr bool operator>=(const floating_point<A>& a, const B& b);
(1) template <typename A, typename B>
constexpr 'hidden' operator+(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(2) template <typename A, typename B>
constexpr 'hidden' operator+(const A& a, const floating_point<B>& b) noexcept;
(3) template <typename A, typename B>
constexpr 'hidden' operator+(const floating_point<A>& a, const B& b) noexcept;
(4) template <typename A, typename B>
constexpr 'hidden' operator-(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(5) template <typename A, typename B>
constexpr 'hidden' operator-(const A& a, const floating_point<B>& b) noexcept;
(6) template <typename A, typename B>
constexpr 'hidden' operator-(const floating_point<A>& a, const B& b) noexcept;
(7) template <typename A, typename B>
constexpr 'hidden' operator*(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(8) template <typename A, typename B>
constexpr 'hidden' operator*(const A& a, const floating_point<B>& b) noexcept;
(9) template <typename A, typename B>
constexpr 'hidden' operator*(const floating_point<A>& a, const B& b) noexcept;
(10) template <typename A, typename B>
constexpr 'hidden' operator/(const floating_point<A>& a, const floating_point<B>& b) noexcept;
(11) template <typename A, typename B>
constexpr 'hidden' operator/(const A& a, const floating_point<B>& b) noexcept;
(12) template <typename A, typename B>
constexpr 'hidden' operator/(const floating_point<A>& a, const B& b) noexcept;
Returns: The result of the binary operation of the stored floating point value in the ts::floating_point. The type is a ts::floating_point of the bigger floating point type.
Notes: These functions do not participate in overload resolution, unless A
and B
are both floating point types.
type_safe::operator>>
template <typename Char, class CharTraits, typename FloatT>
std::basic_istream<Char, CharTraits>& operator>>(std::basic_istream<Char, CharTraits>& in, floating_point<FloatT>& f);
Effects: Reads a float from the std::istream and assigns it to the given ts::floating_point. \module types \output_section Input/output
type_safe::operator<<
template <typename Char, class CharTraits, typename FloatT>
std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& out, const floating_point<FloatT>& f);
Effects: Converts the given ts::floating_point to the underlying floating point and writes it to the std::ostream. \module types